# flask_sqlalchemy模块是对sql基本操作的一个封装模块
# python -m pip install flask_sqlalchemy
# 使用了mysql，所以还要引入MySQLdb模块MySQLdb仅支持python2,所以可以使用PyMySQL
# python -m pip install PyMySQL
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
# SQLAlchemy需要使用到MySQLdb模块，python3使用PyMySQL代替
# 需要将pymysql转为mysqldb
import pymysql
pymysql.install_as_MySQLdb() # 后面可以import MySQLdb模块

app = Flask(__name__)

# 配置数据库连接
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:@localhost:3306/test'
# 禁用sql修改跟踪，后期版本将会禁用
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# 数据库实例
db = SQLAlchemy(app)

# 定义数据库模型，与数据库表对应, 要继承db.Model模型
class Classroom(db.Model):
    # 设置表名
    __tablename__ = 'classrooms'
    # 定义字段
    id = db.Column(db.Integer, primary_key=True) # int 主键
    name = db.Column(db.String(20), unique=True) # string 唯一键
    # 一对多的关系中，可以使用关联引用
    # relationship的第一个参数为另一方的模型名
    # backref代表被引用一方可以使用的属性
    # 此处Student的实例可以直接通过s.classroom获取反向班级实体
    students = db.relationship('Student', backref='classroom')
    # 输出格式化
    def __repr__(self):
        return '<Classroom %s %s>' % (self.id, self.name)

    __str__ = __repr__ # 观察、打印数据，__str__特殊方法取__repr__

class Student(db.Model):
    __tablename__ = 'students'

    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String(10), unique=True)
    roomId = db.Column(db.Integer, db.ForeignKey('classrooms.id')) # 外键, 表名.id
    # 输出格式化
    def __repr__(self):
        return '<Student %s %s>' % (self.id, self.name)

def crud():
    db.drop_all() # 删除模型对应的表
    db.create_all() # 创建模型对应的表
    # 增
    cr = Classroom(name='class-1')
    db.session.add(cr)
    db.session.commit()

    st1 = Student(name='tom', roomId=cr.id)
    st2 = Student(name='cat', roomId=cr.id)
    db.session.add_all([st1,st2])
    db.session.commit()

    print(st1, st1.classroom) # student使用backref关联引用
    print(cr, cr.students) # classroom使用关联引用 

    # query
    print(Student.query.all(), Student.query.get(1)) # 查询所有和id=1的数据
    print(Classroom.query.first(), Classroom.query.count()) # 第一条和总数
    # 查询id=1的一条，下面2种方式等效
    print(Student.query.filter_by(id=1).first()) 
    print(Student.query.filter(Student.id==1).first()) # filter功能更强大

    # update
    st2.name = 'tom1'
    db.session.merge(st2)
    print('merge -> ', st2)

    # del
    db.session.delete(st1)
    db.session.commit()

    print(cr.students)
    # 更多数据库操作查看flask_alchemy的api文档，git上有


if __name__ == '__main__':
    crud()
    # app.run(debug=True)